import { Injectable } from '@angular/core';
import { loadModules, loadScript } from 'esri-loader';
import { BehaviorSubject } from 'rxjs';
import esri = __esri;

@Injectable({
  providedIn: 'root'
})
export class ArcgisApiService {
  loaded$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);

  constructor() {
    this.loaded$.subscribe(loaded => {
      if (!loaded) {
        loadScript({
          url: 'https://js.arcgis.com/4.10/dojo/dojo.js' //配置dojo地址
          // url: 'https://localhost/library/4.10/dojo/dojo.js'
        })
          .then(() => {
            this.loaded$.next(true);
          }).catch(err => this.loaded$.next(true));
      }
    });
  }
  /**
   * 
   * @param opts 底图加载
   */
  constructBaseMap(opts: { baseLayers: any }): Promise<any[]> {
    return new Promise((resolve, reject) => {
      loadModules(['esri/Basemap'])
        .then(([Basemap]) => {
          try {
            const basemap = new Basemap({
              baseLayers: opts.baseLayers
            });
            resolve(basemap);
          } catch (error) {
            reject(error);
          }
        });
    });
  }
  /**
   * 
   * @param opts 地图加载
   */
  constructMap(opts: { basemap: any; elevation: boolean; ground?: any }): Promise<any> {
    return new Promise((resolve, reject) => {
      loadModules(['esri/Map'])
        .then(([Map]) => {
          const map = new Map({
            basemap: opts.basemap
          });
          if (opts.elevation) {
            map.ground = 'world-elevation';
          }
          resolve(map);
        });
    });
  }
  /**
   * 创建地图控制器
   * @param opts 
   */
  constructMapView(opts: {
    center: number[];
    zoom: number;
    container: string;
    map: any;
    padding?: any;
  }): Promise<any[]> {
    return new Promise((resolve, reject) => {
      loadModules(['esri/views/MapView'])
        .then(([MapView]) => {
          const view = new MapView({
            center: opts.center,
            zoom: opts.zoom,
            map: opts.map,
            container: opts.container,
            padding: opts.padding ? opts.padding : {}
          });
          view.when(() => {
            resolve(view);
          });
        });
    });
  }
  /**
   * 
   * @param opts 
   */
  constructSceneView(opts: {
    center: number[];
    zoom?: number;
    container: string;
    map: any;
    camera?: any;
    scale?: any;
    padding?: any;
  }): Promise<any[]> {
    return new Promise((resolve, reject) => {
      loadModules(['esri/views/SceneView'])
        .then(([SceneView]) => {
          const view = new SceneView({
            center: opts.center,
            zoom: opts.zoom,
            scale: opts.scale,
            map: opts.map,
            camera: opts.camera,
            container: opts.container,
            padding: opts.padding ? opts.padding : {}
          });
          view.when(() => {
            resolve(view);
          });
        });
    });
  }
  /**
   * 
   * @param opts 加载图层
   */
  constructTileLayer(opts: {
    url: string
  }): Promise<any[]> {
    return new Promise((resolve, reject) => {
      loadModules(['esri/layers/TileLayer'])
        .then(([TileLayer]) => {
          const tilelyr = new TileLayer({ url: opts.url });
          resolve(tilelyr);
        });
    });
  }
  /**
 * 
 * @param opts 加载影像图层
 */
  constructMapImageLayer(opts: {
    url: string
  }): Promise<any[]> {
    return new Promise((resolve, reject) => {
      loadModules(['esri/layers/MapImageLayer'])
        .then(([MapImageLayer]) => {
          const tilelyr = new MapImageLayer({ url: opts.url });
          resolve(tilelyr);
        });
    });
  }
  /**
   * 
   * @param opts 加载数据图层
   */
  constructFeatureLayer(opts: {
    url: string, outFields: string[], // used by queryFeatures
    popupTemplate: any
  }): Promise<any[]> {
    return new Promise((resolve, reject) => {
      loadModules(['esri/layers/FeatureLayer'])
        .then(([FeatureLayer]) => {
          const tilelyr = new FeatureLayer({
            url: opts.url, outFields: opts.outFields, // used by queryFeatures
            popupTemplate: opts.popupTemplate
          });
          resolve(tilelyr);
        });
    });
  }


  /**
   * 
   * @param opts 加载天地图
   */
  constructWebTileLayer(opts: {
    url: string,
    layername: string,
    tileMatrixSet: string
    //  outFields: string[], // used by queryFeatures
    // popupTemplate: any
  }): Promise<any[]> {
    return new Promise((resolve, reject) => {
      loadModules(['esri/layers/WebTileLayer'])
        .then(([WebTileLayer]) => {
          const tilelyr = new WebTileLayer({
            urlTemplate: opts.url + "?service=wmts&request=gettile&version=1.0.0&layer=" + opts.layername + "&tilematrixset=" + opts.tileMatrixSet + "&format=tiles&tilematrix={level}&tilerow={row}&tilecol={col}&tk=3c2668bb478871162cb471c9d1cf53e0",
            // urlTemplate: opts.url,
            subDomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"],
          });
          resolve(tilelyr);
        });
    });
  }
  /**
   * 
   * @param opts 加载天地图
   */
  constructWebTileLayers(opts: {
    url: string,
    layername: string,
    tileMatrixSet: string
    //  outFields: string[], // used by queryFeatures
    // popupTemplate: any
  }[]): Promise<any[]> {
    return new Promise((resolve, reject) => {
      loadModules(['esri/layers/WebTileLayer'])
        .then(([WebTileLayer]) => {
          const tilelyrs = [];
          for (var i in opts) {
            const tilelyr = new WebTileLayer({
              urlTemplate: opts[i].url + "?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=" + opts[i].layername + "&TILEMATRIXSET=" + opts[i].tileMatrixSet + "&FORMAT=tiles&TILEMATRIX={level}&TILEROW={row}&TILECOL={col}&tk=3c2668bb478871162cb471c9d1cf53e0",
              // urlTemplate: opts.url,
              subDomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"],
            });
            tilelyrs.push(tilelyr);
          }

          resolve(tilelyrs);

        });
    });
  }


  // mercatorTolonlat(lat, lon) {
  //   var lonlat = { x: 0, y: 0 };
  //   var x = lat / 20037508.34 * 180;
  //   var y = lon / 20037508.34 * 180;
  //   y = 180 / Math.PI * (2 * Math.atan(Math.exp(y * Math.PI / 180)) - Math.PI / 2);
  //   lonlat.x = x;
  //   lonlat.y = y;
  //   return lonlat;
  // }
  mercatorTolonlat(opts: {
    lat: string,
    lon: string,
  }): Promise<any[]> {
    return new Promise((resolve, reject) => {
      loadModules(['esri/tasks/support/ProjectParameters', 'esri/geometry/Point', 'esri/geometry/SpatialReference', 'esri/tasks/GeometryService'])
        .then(([ProjectParameters, Point, SpatialReference, GeometryService]) => {
          var point = new Point(parseFloat(opts.lon), parseFloat(opts.lat), new SpatialReference({ wkid: parseInt('3857') }));
          const PrjParams = new ProjectParameters();
          PrjParams.geometries = [point];//几何类型数组，比如多个点可以批量转换

          PrjParams.outSR = new SpatialReference({ wkid: 4490 });//需要输出的坐标系，4490代表是2000的地理坐标系，天地图就是这个坐标系
          var geometryService = new GeometryService('https://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/Geometry/GeometryServer');
          var outputpoints1;
          geometryService.project(PrjParams, function (outputpoints) {

            console.log("经度：" + outputpoints[0].x + ",纬度：" + outputpoints[0].y);
          });

          // resolve(outputpoints1);
        });
    });
  }
  createMark(opts: {
    lat: string,
    lon: string,
    imgutl: string,
  }): Promise<any[]> {
    return new Promise((resolve, reject) => {
      loadModules(['esri/tasks/support/ProjectParameters', 'esri/geometry/Point', 'esri/geometry/SpatialReference', 'esri/tasks/GeometryService'])
        .then(([ProjectParameters, Point, SpatialReference, GeometryService]) => {
          var point = new Point(parseFloat(opts.lon), parseFloat(opts.lat), new SpatialReference({ wkid: parseInt('3857') }));
          const PrjParams = new ProjectParameters();
          PrjParams.geometries = [point];//几何类型数组，比如多个点可以批量转换

          PrjParams.outSR = new SpatialReference({ wkid: 4490 });//需要输出的坐标系，4490代表是2000的地理坐标系，天地图就是这个坐标系
          var geometryService = new GeometryService('https://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/Geometry/GeometryServer');
          var outputpoints1;
          geometryService.project(PrjParams, function (outputpoints) {

            console.log("经度：" + outputpoints[0].x + ",纬度：" + outputpoints[0].y);
          });

          // resolve(outputpoints1);
        });
    });
  }
}
